<template>
  <div>
    <Card title="发送邮件设置" class="w-1/2 !m-10px min-w-700px">
      <Form layout="vertical" :model="data" ref="emailForm">
        <FormItem label="邮件来自" name="mailFrom" required>
          <Input v-model:value="data.mailFrom" @change="formItemChange" />
        </FormItem>
        <FormItem label="SMTP 供应商" name="providerId">
          <Select v-model:value="data.providerId" @change="providerIdChange">
            <SelectOption value="CUSTOM">Custom</SelectOption>
            <SelectOption value="GOOGLE">Google</SelectOption>
            <SelectOption value="OFFICE_365">Office 365</SelectOption>
            <SelectOption value="SENDGRID">SendGrid</SelectOption>
          </Select>
        </FormItem>
        <Collapse expandIconPosition="right" class="!mb-24px" :default-active-key="['1']">
          <CollapsePanel header="Connection settings" :forceRender="true" key="1">
            <FormItem label="SMTP协议" name="smtpProtocol">
              <Select v-model:value="data.smtpProtocol" @change="formItemChange">
                <SelectOption value="smtp">SMTP</SelectOption>
                <SelectOption value="smtps">SMTPS</SelectOption>
              </Select>
            </FormItem>
            <FormItem label="SMTP主机" name="smtpHost" required>
              <Input v-model:value="data.smtpHost" @change="formItemChange" />
            </FormItem>
            <FormItem label="SMTP端口" name="smtpPort" required>
              <Input v-model:value="data.smtpPort" :maxlength="5" @change="formItemChange" />
            </FormItem>
            <FormItem label="超时时间(毫秒)" name="timeout" required>
              <Input v-model:value="data.timeout" :maxlength="6" @change="formItemChange" />
            </FormItem>
            <FormItem name="enableTls" required>
              <div class="!flex !items-center">
                <Switch v-model:checked="data.enableTls" @change="formItemChange" />
                <span class="ml-12px">启用TLS</span>
              </div>
            </FormItem>
            <FormItem label="TLS版本" name="tlsVersion" v-show="data.enableTls">
              <Select v-model:value="data.tlsVersion" @change="formItemChange">
                <SelectOption value="TLSv1">TLSv1</SelectOption>
                <SelectOption value="TLSv1.1">TLSv1.1</SelectOption>
                <SelectOption value="TLSv1.2">TLSv1.2</SelectOption>
                <SelectOption value="TLSv1.3">TLSv1.3</SelectOption>
              </Select>
            </FormItem>
            <FormItem name="enableProxy" required>
              <div class="!flex !items-center">
                <Switch v-model:checked="data.enableProxy" @change="formItemChange" />
                <span class="ml-12px">启用代理</span>
              </div>
            </FormItem>
            <FormItem label="代理主机" name="proxyHost" required v-if="data.enableProxy">
              <Input v-model:value="data.proxyHost" @change="formItemChange" />
            </FormItem>
            <FormItem label="代理端口" name="proxyPort" required v-if="data.enableProxy">
              <InputNumber
                v-model:value="data.proxyPort"
                min="1"
                max="65535"
                @change="formItemChange"
              />
            </FormItem>
            <Row :gutter="20" v-if="data.enableProxy">
              <Col span="12">
                <FormItem label="代理用户" name="proxyUser">
                  <Input v-model:value="data.proxyUser" @change="formItemChange" />
                </FormItem>
              </Col>
              <Col span="12">
                <FormItem label="代理密码" name="proxyPassword">
                  <InputPassword v-model:value="data.proxyPassword" @change="formItemChange" />
                </FormItem>
              </Col>
            </Row>
          </CollapsePanel>
        </Collapse>
        <FormItem label="用户名" name="username">
          <Input v-model:value="data.username" @change="formItemChange" />
        </FormItem>
        <FormItem name="enableOauth2" v-if="data.providerId !== 'SENDGRID'">
          <Button :type="data.enableOauth2 === false ? 'primary' : 'default'" @click="chooseBasic"
            >Basic</Button
          >
          <Button :type="data.enableOauth2 === true ? 'primary' : 'default'" @click="chooseOAuth2"
            >OAuth2</Button
          >
        </FormItem>
        <FormItem v-if="data.enableOauth2 === false">
          <Checkbox v-model:checked="data.editPassword" @change="formItemChange">修改密码</Checkbox>
        </FormItem>
        <FormItem
          label="密码"
          name="password"
          v-if="data.enableOauth2 === false && data.editPassword === true"
        >
          <InputPassword v-model:value="data.password" @change="formItemChange" />
        </FormItem>
        <Row :gutter="20" v-if="data.enableOauth2 === true && data.providerId !== 'SENDGRID'">
          <Col span="12">
            <FormItem label="客户端ID" name="clientId" required>
              <Input v-model:value="data.clientId" @change="formItemChange" />
            </FormItem>
          </Col>
          <Col span="12">
            <FormItem label="客户机密" name="clientSecret" required>
              <Input v-model:value="data.clientSecret" @change="formItemChange" />
            </FormItem>
          </Col>
          <Col span="24" v-if="data.providerId === 'OFFICE_365'">
            <FormItem label="Directory(tenant)Id" name="providerTenantId" required>
              <Input v-model:value="data.providerTenantId" @change="providerTenantIdChange" />
            </FormItem>
          </Col>
          <Col span="24">
            <Collapse expandIconPosition="right" class="!mb-24px" :default-active-key="['1']">
              <CollapsePanel header="高级设置" :forceRender="true" key="1">
                <Row :gutter="20">
                  <Col span="12">
                    <FormItem
                      label="授权URI"
                      name="authUri"
                      required
                      :rules="[
                        {
                          pattern: urlPattern,
                          message: '无效的URI格式',
                        },
                      ]"
                    >
                      <Input v-model:value="data.authUri" @change="formItemChange" />
                    </FormItem>
                  </Col>
                  <Col span="12">
                    <FormItem
                      label="TokenURI"
                      name="tokenUri"
                      required
                      :rules="[
                        {
                          pattern: urlPattern,
                          message: '无效的URI格式',
                        },
                      ]"
                    >
                      <Input v-model:value="data.tokenUri" @change="formItemChange" />
                    </FormItem>
                  </Col>
                  <Col span="24">
                    <InputList
                      inputTitle="范围"
                      :initInputDataList="data.scope"
                      :dataChange="data.scope"
                      @getInputDataList="InputListChange"
                    />
                  </Col>
                </Row>
              </CollapsePanel>
            </Collapse>
          </Col>
          <Col span="4">
            <FormItem label="协议">
              <Select v-model:value="data.protocol" @change="protocolChange">
                <SelectOption value="http:">HTTP</SelectOption>
                <SelectOption value="https:">HTTPS</SelectOption>
              </Select>
            </FormItem>
          </Col>
          <Col span="10">
            <FormItem label="域名">
              <Input v-model:value="data.domainName" @change="domainNameChange" />
            </FormItem>
          </Col>
          <Col span="10">
            <FormItem label="从定向url模板" name="redirectUri">
              <Input v-model:value="data.redirectUri" readonly>
                <template #suffix>
                  <Button type="text" shape="circle" @click="copy(data.redirectUri)" size="small">
                    <Icon icon="ant-design:copy-outlined" />
                  </Button>
                </template>
              </Input>
            </FormItem>
          </Col>
          <Col>
            <Button type="primary" @click="genToken" :disabled="!canGenerate"
              >Generate access token</Button
            >
          </Col>
        </Row>
        <div class="float-right">
          <Button class="mr-10px" @click="testMail">发送测试邮件</Button>
          <Button type="primary" class="mr-10px" @click="save" :disabled="!isEdit">保存</Button>
        </div>
      </Form>
    </Card>
  </div>
</template>

<script lang="ts" setup>
  import {
    Card,
    Collapse,
    CollapsePanel,
    Form,
    FormItem,
    Input,
    Select,
    SelectOption,
    Row,
    Col,
    Checkbox,
    Switch,
    InputNumber,
    InputPassword,
    Button,
  } from 'ant-design-vue';
  import InputList from '/@/components/thingsborad/sharedComponents/modules/InputList.vue';
  import { getEmailSetting } from '/@/api/thingsborad/settings/BasicSetting/basicSetting';
  import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  import { useMessage } from '/@/hooks/web/useMessage';
  import Icon from '/@/components/Icon';
  import { CustomData, GoogleData, Office365Data, SendGridData } from './email.data';
  import { onMounted, ref, watch } from 'vue';
  import {
    postEmailSetting,
    sendTestEmail,
    generateToken,
  } from '/@/api/thingsborad/settings/BasicSetting/basicSetting';
  import _ from 'lodash';
  let data = ref<Recordable>({
    mailFrom: null,
    providerId: null,
    username: null,
    enableOauth2: null,
    clientId: null,
    clientSecret: null,
    protocol: null,
    domainName: null,
    redirectUri: null,
    password: null,
    editPassword: false,
    tokenUri: null,
    authUri: null,
    scope: [],
    smtpHost: null,
    smtpPort: null,
    timeout: null,
    smtpProtocol: null,
    enableTls: false,
    enableProxy: false,
    tlsVersion: null,
    proxyHost: null,
    proxyPort: null,
    proxyUser: null,
    providerTenantId: null,
  });
  let emailForm = ref<any>({});
  let resEmail = ref<Recordable>({});
  const urlPattern =
    /^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.,?+=&%@\-/]*)?$/;
  let isEdit = ref<boolean>(false);
  let canGenerate = ref<boolean>(true);
  watch(
    () => isEdit.value,
    (nVal) => {
      canGenerate.value = !nVal;
    },
  );
  const { clipboardRef } = useCopyToClipboard();
  const { createMessage } = useMessage();
  onMounted(async () => {
    let res: Recordable = {};
    try {
      res = await getEmailSetting();
    } catch (e) {
      console.error('获取邮箱设置失败', e);
    }
    resEmail.value = res;
    Object.assign(data.value, res.jsonValue);
    if (data.value.redirectUri) {
      let parts = data.value.redirectUri.split('/');
      data.value.protocol = parts[0] === 'http:' ? 'http:' : 'https:';
      data.value.domainName = parts[2];
    } else {
      data.value.redirectUri =
        data.value.protocol + '//' + data.value.domainName + '/api/admin/mail/oauth2/code';
    }
    data.value.scope.forEach((item, index) => {
      data.value.scope[index] = { text: item };
    });
  });
  function copy(data: string) {
    clipboardRef.value = data;
    createMessage.success('复制成功');
  }
  function InputListChange(change: any) {
    data.value.scope = change;
  }
  //协议更改
  function protocolChange(change: any) {
    let parts = data.value.redirectUri.split('/');
    parts[0] = change;
    data.value.redirectUri = parts.join('/');
    isEdit.value = true;
  }
  //域名更改
  function domainNameChange(change: any) {
    let parts = data.value.redirectUri.split('/');
    parts[2] = change.target.value;
    data.value.redirectUri = parts.join('/');
    isEdit.value = true;
  }
  //SMTP供应商更改
  function providerIdChange(change: any) {
    if (change === 'CUSTOM') {
      Object.assign(data.value, CustomData);
    }
    if (change === 'GOOGLE') {
      Object.assign(data.value, GoogleData);
    }
    if (change === 'OFFICE_365') {
      Object.assign(data.value, Office365Data);
    }
    if (change === 'SENDGRID') {
      Object.assign(data.value, SendGridData);
    }
    if (!data.value.domainName) {
      data.value.domainName = window.location.hostname;
      data.value.redirectUri =
        data.value.protocol + '//' + data.value.domainName + '/api/admin/mail/oauth2/code';
    }
    isEdit.value = false;
  }
  function chooseBasic() {
    data.value.enableOauth2 = false;
    isEdit.value = true;
  }

  function chooseOAuth2() {
    data.value.enableOauth2 = true;
    isEdit.value = true;
  }

  async function save() {
    try {
      await emailForm.value.validate();
      let param = _.cloneDeep(data.value);
      param.scope = param.scope.map((value) => value.text);
      Object.assign(resEmail.value.jsonValue, param);
      await postEmailSetting(resEmail.value);
      isEdit.value = false;
    } catch (e) {
      console.error('保存失败', e);
    }
  }

  async function testMail() {
    try {
      await emailForm.value.validate();
      let param = _.cloneDeep(data.value);
      if (!param.password) {
        delete param.password;
      }
      param.scope = param.scope.map((value) => value.text);
      Object.assign(resEmail.value.jsonValue, param);
      await sendTestEmail(resEmail.value);
      createMessage.success('发送成功');
    } catch (e) {
      console.error('保存失败', e);
      createMessage.error('发送失败');
    }
  }

  function formItemChange() {
    isEdit.value = true;
  }
  //Directory(tenant)Id更改
  function providerTenantIdChange() {
    data.value.authUri =
      'https://login.microsoftonline.com/' + data.value.providerTenantId + '/oauth2/v2.0/authorize';
    data.value.tokenUri =
      'https://login.microsoftonline.com/' + data.value.providerTenantId + '/oauth2/v2.0/token';
    isEdit.value = true;
  }
  async function genToken() {
    generateToken().then((uri) => {
      window.location.href = uri;
    });
  }
</script>
